﻿package net.libra.loader
{
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	/**
	 * 外部资源加载器
	 * @author DanielLu
	 */
	public class AssetsLoader extends Loader implements ILoader 
	{
		//加载到子域
		public static const TARGET_CHILD : String = "child";
		//加载到同域
		public static const TARGER_SAME : String = "same";
		//加载到新域
		public static const TARGET_NEW : String = "new";

		private var loading : Boolean;
		private var lastPath : String;
		private var currentPath : String;
		private var applicationDomain : String;

		/**
		 * 创建一个<code>AssetLoader</code>对象。
		 * @param applicationDomain		加载到的应用程序域
		 */
		public function AssetsLoader (applicationDomain : String = "same")
		{
			super( );
			this.loading = false;
			this.applicationDomain = applicationDomain;
			this.contentLoaderInfo.addEventListener( Event.COMPLETE , __onLoadCompleted , false , 1000000 );
			this.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR , __onLoadError , false , 1000000 );
			this.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS , __onLoadProgress , false , 1000000 );
		}

		private function __onLoadCompleted (e : Event) : void
		{
			this.loading = false;
			this.fireComplete( );
			this.lastPath = this.currentPath;
		}

		private function __onLoadError (e : Event) : void
		{
			this.loading = false;
			this.fireFailure( );
		}

		private function __onLoadProgress (e : ProgressEvent) : void
		{
			this.fireProgress( e );
		}

		/**
		 * 设置加载的路径
		 * @param path		加载的路径
		 */
		public function setPath (path : String) : void
		{
			this.currentPath = path;
		}

		/**
		 * 返回加载的路径
		 * @return		加载的路径
		 */
		public function getPath () : String
		{
			return this.currentPath;
		}

		/**
		 * 设置加载的应用程序域
		 * @param applicationDomain		加载到的应用程序域
		 */
		public function setApplicationDomain (applicationDomain : String) : void
		{
			this.applicationDomain = applicationDomain;
		}

		/**
		 * 返回加载的应用程序域
		 * @return		加载的应用程序域
		 */
		public function getApplicationDomain () : String
		{
			return this.applicationDomain;
		}

		//------------------------------------------------------------------------------------------------
		override public function close () : void
		{
			try
			{
				super.close( );
				this.loading = false;
			}
			catch(e : Error)
			{
				this.loading = false;
			}
		}

		override public function load (request : URLRequest, context : LoaderContext = null) : void
		{
			if(! this.loading)
			{
				super.load( request , context );
				this.loading = true;
			}
		}
		public function doLoadPath(path:String):void
		{
			this.setPath(path);
			doLoad();
		}
		override public function loadBytes (bytes : ByteArray, context : LoaderContext = null) : void
		{
			if(! this.loading)
			{
				super.loadBytes( bytes , context );
				this.loading = true;
			}
		}

		override public function unload () : void
		{
			super.unload( );
			this.currentPath = "";
			this.lastPath = "";
		}

		/**
		 * 加载外部资源。
		 */
		public function doLoad () : void
		{
			if(! this.loading && this.lastPath != this.currentPath)
			{
				var context : LoaderContext = new LoaderContext( );
				if(this.applicationDomain == TARGET_CHILD)
				{
					context.applicationDomain = new ApplicationDomain( ApplicationDomain.currentDomain );
				}
				else if(this.applicationDomain == TARGET_NEW)
				{
					context.applicationDomain = new ApplicationDomain( );
				}
				else
				{
					context.applicationDomain = ApplicationDomain.currentDomain;
				}
				super.load( new URLRequest( this.currentPath ) , context );
				this.loading = true;
			}
		}

		/**
		 * 获取加载的对象。
		 * @return		Loader对象。
		 */
		public function getData () : Object
		{
			return this;
		}

		/**
		 * 是否正在加载
		 * @return		当前对象是否正在加载资源
		 */
		public function isLoading () : Boolean
		{
			return this.loading;
		}

		//--------------------------------------------------------------
		/**
		 * @inheritDoc
		 */
		public function addCompleteListener (listener : Function,priority : int = 0,useWeakReference : Boolean = false) : void
		{
			this.addEventListener( LoadEvent.ON_COMPLETE , listener , false , priority , useWeakReference );
		}

		/**
		 * @inheritDoc
		 */
		public function removeCompleteListener (listener : Function) : void
		{
			this.removeEventListener( LoadEvent.ON_COMPLETE , listener );
		}

		/**
		 * 发送加载完成的事件
		 */
		protected function fireComplete () : void
		{
			this.dispatchEvent( new LoadEvent( LoadEvent.ON_COMPLETE , this ) );
		}

		/**
		 * @inheritDoc
		 */
		public function addFailureListener (listener : Function,priority : int = 0,useWeakReference : Boolean = false) : void
		{
			this.addEventListener( LoadEvent.ON_FAILURE , listener , false , priority , useWeakReference );
		}

		/**
		 * @inheritDoc
		 */
		public function removeFailureListener (listener : Function) : void
		{
			this.removeEventListener( LoadEvent.ON_FAILURE , listener );
		}

		/**
		 * 发送加载失败的事件。
		 */
		protected function fireFailure () : void
		{
			this.dispatchEvent( new LoadEvent( LoadEvent.ON_FAILURE , this ) );
		}

		/**
		 * 空实现。
		 * @inheritDoc
		 */
		public function addProgressListener (listener : Function,priority : int = 0,useWeakReference : Boolean = false) : void
		{
			this.addEventListener( ProgressEvent.PROGRESS , listener , false , priority , useWeakReference );
		}

		/**
		 * 空实现。
		 * @inheritDoc
		 */
		public function removeProgressListener (listener : Function) : void
		{
			this.removeEventListener( ProgressEvent.PROGRESS , listener );
		}

		/**
		 * 发送加载失败的事件。
		 */
		protected function fireProgress (e : ProgressEvent ) : void
		{
			this.dispatchEvent( e );
		}
	}
}
